import fs from 'fs'
import path from 'path'
import { cookieToJson } from '../utils'
import request from '../utils/request'
function random(min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

const special = {
  'm1_yq_address.js': '/m1/yq/address',
  'm1_yq_info.js': '/m1/yq/info',
  'm1_wea_now.js': '/m1/wea/now',
  'm1_wea_seven.js': '/m1/wea/seven',
}

export default (app) => {
  // 映射特殊请求路径
  const dirPath = path.join(__dirname, '.')
  // check dir
  fs.readdirSync(dirPath)
    .reverse()
    .forEach(async (dir) => {
      if (dir.endsWith('.js')) return
      // console.log('dir: ', dir)
      // check file
      const filePath = path.join(__dirname, dir, '.')
      fs.readdirSync(filePath)
        .reverse()
        .forEach(async (file) => {
          if (!file.endsWith('.js')) return
          // console.log('file: ', file)
          const fileName = file.replace(/\.js$/i, '')
          const route =
            file in special
              ? special[file]
              : `/${dir}/` + fileName.replace(/_/g, '/')
          console.log('route: ', route)
          const params = {
            app,
            dir,
            file,
            route,
            path,
          }
          if (dir === 'auth') {
            handleAuthApi(params)
          } else if (dir === 'haut') {
            handleHautApi(params)
          } else {
            handleBaseApi(params)
          }
        })
    })
}

const handleBaseApi = async ({ app, dir, file, route }) => {
  const ex = await import(`./${dir}/${file.replace(/\.js$/i, '')}.js`)
  const e = ex?.default
  if (!e) return
  app.use(route, (req, res) => {
    ;[req.query, req.body].forEach((item) => {
      if (typeof item.cookie === 'string') {
        item.cookie = cookieToJson(decodeURIComponent(item.cookie))
      }
    })
    const query = Object.assign({}, req.query, req.body, req.files, req.headers)
    query.cookie = req.cookies
    e(query, request)
      .then((answer) => {
        console.log('[OK]', decodeURIComponent(req.originalUrl))
        res.append('Set-Cookie', answer.cookie)
        if (route.indexOf('wy/') !== -1) {
          answer = answer.body
        }
        res.status(200).send(answer)
      })
      .catch((err) => {
        console.log('[ERR]', decodeURIComponent(req.originalUrl), {
          status: 500,
          body: err.name + ':' + err.message,
        })
        res.status(500).send({ error: err.message })
        // if (answer.body.code == '301') answer.body.msg = '需要登录'
        // res.append('Set-Cookie', answer.cookie)
        // res.status(answer.status).send(answer.body)
      })
  })
}

const handleHautApi = async ({ app, dir, file, route }) => {
  const ex = await import(`./${dir}/${file.replace(/\.js$/i, '')}.js`)
  const e = ex?.default
  if (!e) return
  app.use(route, (req, res) => {
    const query = Object.assign(
      {},
      { cookies: req.cookies },
      { headers: req.headers },
      req.query,
      req.body,
      req.files
    )
    // console.log(query)
    const hasCookies = Object.keys(query.cookies).includes('HAUT_STU')
    if (hasCookies) {
      res.status(500).send({ error: 'wait a moment' })
      return
    }
    e(query, request)
      .then((answer) => {
        let d = new Date()
        d.setTime(d.getTime() + 5 * 1000)
        d = d.toUTCString()
        const returnCookie = `HAUT_STU=${answer.testId}; Path=/haut; Expires=${d};`
        console.log('[OK]', decodeURIComponent(req.originalUrl))
        res.append('Set-Cookie', returnCookie)
        res.status(200).send(answer)
      })
      .catch((err) => {
        console.log('[ERR]', decodeURIComponent(req.originalUrl), {
          status: 500,
          body: err.name + ':' + err.message,
        })
        res.status(500).send({ error: err.message })
      })
  })
}

const handleAuthApi = async ({ app, dir, file, route }) => {
  const tkFlag = file === 'token.js'
  route =
    `/${dir}/` +
    file.replace(/\.js$/i, '').replace(/_/g, '/') +
    (tkFlag ? '/:stu' : '/:id/:tk')
  const ex = await import(`./${dir}/${file.replace(/\.js$/i, '')}.js`)
  let e = ex?.default
  if (tkFlag) e = ex?.fun
  if (!e) return
  app.use(route, (req, res) => {
    if (req.cookies === undefined) {
      req.cookies.HX_STU = 'Mono' + random(1, 100)
    }
    const ck = req.cookies.HX_STU || 'Mono' + random(1, 100)
    const query = Object.assign(
      {},
      req.query,
      req.params,
      req.body,
      req.files,
      req.headers
    )

    // 校验临时凭证，IV密钥 + Cookie Stu + 时间戳去除后4位
    if (!tkFlag) {
      const signaVal = require('./auth/token.js').signa(ck)
      console.log('[Signa]', signaVal)
      if (query.tk !== signaVal && !tkFlag) {
        const monoVal = 'Mono' + random(1, 100)
        let monoErr = {}
        console.log('[ERR]', decodeURIComponent(req.originalUrl), monoErr)
        res.cookie('HX_STU', monoVal, { path: '/auth' })
        process.hx = monoVal
        console.log('[Mono]', `>>> ${monoVal} <<<`)
        monoErr = {
          code: 403,
          message: `${monoVal}, Token Error`,
        }
        res.status(403).send(monoErr)
        return
      }
    }
    e(query)
      .then((answer) => {
        console.log('[OK]', decodeURIComponent(req.originalUrl))
        if (tkFlag) {
          // 认证通过也可以修改cookie
          // res.append('Set-Cookie', answer.cookie)
          // res.cookie('HX_STU', answer.cookie, { path: '/auth' })
        }
        res.status(200).send({
          code: 200,
          message: 'success',
          data: tkFlag ? answer.body : answer,
        })
      })
      .catch((err) => {
        console.log('[ERR]', decodeURIComponent(req.originalUrl), {
          status: 500,
          body: err.name + ':' + err.message,
        })
        res.status(500).send({
          code: 500,
          message: err.message,
        })
        // if (answer.body.code == '301') answer.body.msg = '需要登录'
        // res.append('Set-Cookie', answer.cookie)
        // res.status(answer.status).send(answer.body)
      })
  })
}
